/******************************************************************************************
版权所有 2021-2021, 长春理工大学C&I实验室。保留所有权利。
文件名：main.c
作者：Wind    版本：V1.0    日期：2021.6.19
文件描述：
    主程序。
其它说明：

历史修改记录：
1. 2021-6-19:V1.0 Wind
创建。

******************************************************************************************/
//+------------------------------------------------------------------------------------------+
//|                                         头文件包含
//+------------------------------------------------------------------------------------------+
/*|*/#include <stdio.h>
/*|*/#include <stdlib.h>
/*|*/#include <stdbool.h>
/*|*/#include <signal.h>
/*|*/#include <arpa/inet.h>
//|
/*|*/#include "L_RTP.h"
//|
/*|*/#include "mpp40_sys.h"
/*|*/#include "mpp40_vi.h"
/*|*/#include "mpp40_venc.h"
//|
/*|*/#include "mpi_venc.h"
//+------------------------------------------------------------------------------------------+
//|                                          全局变量
//+------------------------------------------------------------------------------------------+
/*|*/static bool program_run = true;
//|
/*|*/static const VENC_PARA_S stVENCpara_chn = 
/*|*/{
/*|*/    .VencChn      = 0,
/*|*/    .enPayLoad    = PT_H264,
/*|*/    .enSize       = PIC_1080P,
/*|*/    .enGopMode    = VENC_GOPMODE_NORMALP,
/*|*/    .u32Gop       = 30,
/*|*/    .enRcMode     = RC_CBR,
/*|*/    .u32FrameRate = 30,
/*|*/    .u32Profile   = 0,
//|    ----------------------------------------
//|    [说明]该参数为VENC接收传感器传入的图像帧
//|    数，当编码帧率小于输入帧率时，若VENC接收
//|    图像数量超过该值则VENC编码停止。
//|    该值为-1时，表示不设限制。
//|    ----------------------------------------
/*|*/    .s32FrameNumber = -1,
/*|*/};
//|
/*|*/static L_STRUCT_RTPSESSION RTPSession=
/*|*/{
/*|*/    .flag_inited=0,
/*|*/};
//|
/*|*/static VI_PARA_S stVI_para = 
/*|*/{
/*|*/    .enAUTOExposure = HI_TRUE,
/*|*/};
//+------------------------------------------------------------------------------------------+
//|  函数名称：sig_handle
//|  功能描述：信号处理
//|  参数说明：信号值
//|  返回值说明：无
//|  备注：
//+------------------------------------------------------------------------------------------+
static void sig_handle(int signo)
{
	if(SIGINT == signo || SIGTERM == signo)
	{
        program_run = false;
	}
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：stream_process
//|  功能描述：码流处理函数
//|  参数说明：VENC通道号，码流包结构体
//|  返回值说明：无
//|  备注：
//+------------------------------------------------------------------------------------------+
static void stream_process(int VencChn, VENC_STREAM_S *pstStream)
{
    if(VencChn == stVENCpara_chn.VencChn)
    {
        for(int i = 0; i < pstStream->u32PackCount; i++)
        {
            RTPSession.pData      = pstStream->pstPack[i].pu8Addr + pstStream->pstPack[i].u32Offset;
			RTPSession.DataLength = pstStream->pstPack[i].u32Len - pstStream->pstPack[i].u32Offset;
			RTPSession.TimeStamp  = pstStream->pstPack[i].u64PTS;
			RTPSession.DataType   = RTP_H264;
            //printf("Chn[%d]:Len[%d]=%d ",VencChn,i,RTPSession.DataLength);
			//printf("TimeStamp:%lld\n",pstStream->pstPack[i].u64PTS);
			L_RTP_Send(&RTPSession);
        }
    }
}

//+------------------------------------------------------------------------------------------+
//|  函数名称：main
//|  功能描述：主函数
//|  参数说明：./文件名 对端IP 对端端口
//|  返回值说明：略
//|  备注：本机IP是自动获得的，需要提前设置好。
//+------------------------------------------------------------------------------------------+
int main(int argc, const char *argv[])
{
    int ret = 0;
    
    /* 传参判断 */
    if(argc != 3)
    {
        printf("Usage:\n");
        printf("    ./filename DestIP DestPort\n");
        exit(0);
    }
    
    /* 安装信号 */
	signal(SIGINT, sig_handle); //注册Ctrl+C信号处理函数
	signal(SIGTERM, sig_handle);//注册无参数kill信号处理函数
    
    /* 设置RTP */
	inet_aton(argv[1], (struct in_addr *)&(RTPSession.u32DestIP));
	RTPSession.DestPort = atoi(argv[2]);
    
    /* 创建RTP会话 */
	ret = L_RTP_CreateSession(&RTPSession);
	if(ret != 0)
	{
		printf("L_RTP_CreateSession failed!\n");
		return -1;
	}
    
	/* 初始化MPP SYS */
    ret = sys_init();
    if(0 != ret)
    {
        printf("[STREAM-ERROR]MPP init failed.\n");
        goto END;
    }
    
    /* 初始化VI */
    ret = vi_init(&stVI_para);
    if(0 != ret)
    {
        printf("[STREAM-ERROR]VI init failed.\n");
        goto END_MPP;
    }
    
    ret = venc_create_chn_and_start(&stVENCpara_chn);
    if(0 != ret)
    {
        printf("[STREAM-ERROR]Create VENC failed!\n");
        goto END_VI;
    }
    
    /* 码流处理 */
    printf("---- RTP Startup ...\n");
    venc_getstream(&program_run, stream_process);
    
    /* 退出处理 */
    venc_deinit(stVENCpara_chn.VencChn);
END_VI:
    vi_uninit();
END_MPP:
    sys_deinit();
END:
    /* 销毁RTP会话 */
	L_RTP_DestorySession(&RTPSession);
    
    return 0;
}
